//
//  PlSSIMBLPlugIn.m
//  Injector
//
//  Created by ∞ on 13/11/07.
//  Copyright 2007 Emanuele Vulcano. All rights reserved.
//

#import "PlSSIMBLPlugIn.h"
#import "PlSAppSpecifier.h"
#import "PlSSIMBLManager.h"

@implementation PlSSIMBLPlugIn

@synthesize identifier, version, appSpecifiers;

- (BOOL) isLoadable {
	return [manager isLoadable:self];
}

- (void) setIsLoadable:(BOOL) loadable {
	[manager setLoadable:loadable forPlugIn:self];
}

- (id) initWithPath:(NSString*) path manager:(PlSSIMBLManager*) m {
#define PlSReturnNilUnless(x) if (!(x)) { [self release]; return nil; }
	if (self = [super init]) {
		manager = m; // weak for non-GC clients.
		
		NSBundle* bundle = [NSBundle bundleWithPath:path];
		PlSReturnNilUnless(bundle);
		
		NSDictionary* info = [bundle infoDictionary];
		PlSReturnNilUnless(info);
		NSArray* targets;
		PlSReturnNilUnless([(targets = [info objectForKey:@"SIMBLTargetApplications"]) isKindOfClass:[NSArray class]]);
		PlSReturnNilUnless(identifier = [[info objectForKey:@"CFBundleIdentifier"] retain]);
		
		id versionObj = [info objectForKey:@"CFBundleVersion"];
		version = versionObj? [versionObj doubleValue] : 0;
		
		NSMutableArray* specs = [NSMutableArray arrayWithCapacity:[targets count]];
		for (NSDictionary* app in targets) {
			NSString* bundleId;
			PlSReturnNilUnless(bundleId = [app objectForKey:@"BundleIdentifier"]);
			PlSReturnNilUnless([bundleId isKindOfClass:[NSString class]]);
			
			if ([bundleId isEqual:@"*"]) {
				[specs removeAllObjects];
				[specs addObject:[PlSAppSpecifier anyApplication]];
				break;
			}
			
			id	maxVObj = [app objectForKey:@"MaxVersion"],
				minVObj = [app objectForKey:@"MinVersion"];
			
			double	maxV = maxVObj? [maxVObj doubleValue] : kPlSAnyVersion,
					minV = minVObj? [minVObj doubleValue] : kPlSAnyVersion;
			
			[specs addObject:[PlSAppSpecifier specifierWithBundleIdentifier:bundleId minVersion:minV maxVersion:maxV]];
		}
		
		NSString* webSite = [[bundle infoDictionary] objectForKey:@"PlSWebSiteURL"];
		if (webSite && [webSite isKindOfClass:[NSString class]] && ([webSite hasPrefix:@"http://"] || [webSite hasPrefix:@"https://"]))
			webSiteURL = [[NSURL URLWithString:webSite] retain];

		NSString* updatesCheck = [bundle objectForInfoDictionaryKey:@"PlSUpdatesCheckURL"];
		if (updatesCheck && [updatesCheck isKindOfClass:[NSString class]])
			updatesCheckURL = [[NSURL URLWithString:updatesCheck] retain];
		
		appSpecifiers = [specs retain];
		plugInBundle = [bundle retain];
	}
	
	return self;
#undef PlSReturnNilUnless
}

- (void) dealloc {
	[appSpecifiers release];
	[super dealloc];
}

+ (id) plugInWithPath:(NSString*) path manager:(PlSSIMBLManager*) manager {
	return [[[self alloc] initWithPath:path manager:manager] autorelease];
}

- (BOOL) loadNow {
	Class c = nil;
	if ([plugInBundle load])
		c = [plugInBundle principalClass];
	if (!c) return NO;
	if ([(id)c respondsToSelector:@selector(pluginDidLoad:)]) // SafariStand fix
		[c performSelector:@selector(pluginDidLoad:) withObject:plugInBundle];
	
	return c != nil;
}

- (NSString*) displayName {
	NSString* dn = [plugInBundle objectForInfoDictionaryKey:@"CFBundleName"];
	if (!dn)
		dn = [[[NSFileManager defaultManager] displayNameAtPath:[plugInBundle bundlePath]] stringByDeletingPathExtension];
	
	return dn;
}

- (BOOL) isManaged {
	return ![[NSBundle bundleWithIdentifier:@"net.culater.SIMBL"] isLoaded];
}

- (NSImage*) icon {
	NSImage* icon = [[NSWorkspace sharedWorkspace] iconForFile:[plugInBundle bundlePath]];
	[icon setSize:NSMakeSize(32, 32)];
	return icon;
}

- (NSString*) userVisiblePath {
	return [plugInBundle bundlePath];
}

- (NSURL*) webSiteURL { return webSiteURL; }
- (NSURL*) updatesCheckURL { return updatesCheckURL; }
- (BOOL) canRemoveByDeletingUserVisiblePath { return YES; }
- (BOOL) canCheckQuarantineOnUserVisiblePath { return YES; }

- (double) currentVersion {
	id v = [plugInBundle objectForInfoDictionaryKey:@"CFBundleVersion"];
	return v? [v doubleValue] : 0.0;
}

- (NSString*) currentShortVersionString {
	return [plugInBundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
}

@end
